#coding=utf-8
'''
Created on 2009-9-4

@author: mengqc
'''
from django.template import Library, Node, TemplateSyntaxError, VariableDoesNotExist
from django.template import resolve_variable
from django.template.context import Context

register = Library()

def import_func_from_str(model_str):
    components = model_str.split('.')
    model = components[-2]
    func = components[-1]
    models = '.'.join(components[:-1])
    m = __import__(models, globals(), locals(), [model], -1)
    return getattr(m, func)


class ExeNode(Node):
    def __init__(self, func, request, template, vargs):
        self.s_func = func
        self.s_request = request
        self.template = template
        self.s_vargs = vargs

    def render(self, context):
        func = import_func_from_str(resolve_variable(self.s_func, context))
        request = resolve_variable(self.s_request, context)
        template = resolve_variable(self.template, context)
        vargs = []
        for arg in self.s_vargs:
            vargs.append(resolve_variable(arg, context))
        return func(request, template, *vargs)
        

def do_exe(parser, token):
    '''
    使用方式：
    {% load lib_tags %}
    {% exe "library.views.exe_test" request "login/exe_test.html" ... %}
    
    定义渲染函数（在library.views.py文件中）：
    def hello(request, template, ...):
        return render_to_response(template)
    '''
    tokens = token.contents.split()
    if len(tokens) < 4:
        raise TemplateSyntaxError(u"'%r' tag requires at least 3 arguments." % tokens[0])
    return ExeNode(tokens[1], tokens[2], tokens[3], tokens[4:])

register.tag('exe', do_exe)


class ExternNode(Node):
    def __init__(self, nodelist, func, request, vargs):
        self.nodelist = nodelist
        self.s_func = func
        self.s_request = request
        self.s_vargs = vargs

    def render(self, context):
        func = import_func_from_str(resolve_variable(self.s_func, context))
        request = resolve_variable(self.s_request, context)
        vargs = []
        for arg in self.s_vargs:
            vargs.append(resolve_variable(arg, context))
            
        return self.nodelist.render(Context(func(request, *vargs)))

def do_extern(parser, token):
    """
    使用方式：
    {% load lib_tags %}
    {% extern "library.views.extern_test" request ... %}
    {{word}}
    {% endextern %}
    
    定义渲染函数（在library.views.py文件中）：
    def hello(request, template, ...):
        return {"word":"hello"}
    """
    nodelist = parser.parse(('endextern',))
    parser.delete_first_token()
    tokens = token.contents.split()
    if len(tokens) < 3:
        raise TemplateSyntaxError(u"'%r' tag requires at least 2 arguments." % tokens[0])
    return ExternNode(nodelist, tokens[1], tokens[2], tokens[3:])

register.tag('extern', do_extern)